package my.suveng.chat.export.task.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.db.Page;
import lombok.extern.slf4j.Slf4j;
import my.suveng.chat.export.task.dao.SysExportTaskMapper;
import my.suveng.chat.export.task.model.domain.SysExportTask;
import my.suveng.chat.export.task.model.domain.SysExportTaskExample;
import my.suveng.chat.export.task.model.result.ErrorWrapper;
import my.suveng.chat.export.task.model.result.Result;
import my.suveng.chat.export.task.model.result.ResultCode;
import my.suveng.util.json.Jackson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author suwenguang
 *
 *         created since 2020/10/4 6:51 下午
 */
@Service
@Slf4j
public class ExportTaskService {

    @Autowired
    private SysExportTaskMapper sysExportTaskMapper;

    /**
     * 前端加载数据
     * 
     * @param condition
     *            搜索条件
     * @param page
     *            分页
     * 
     * @return 数据
     */
    public Result<List<SysExportTask>> loadPageData(SysExportTask condition, Page page) {
        List<SysExportTask> data;
        // 参数
        SysExportTaskExample example = condition.toExample();
        example.setLimit(page.getPageSize());
        example.setOffset((page.getPageNumber() - 1) * page.getPageSize());

        // 查询
        data = sysExportTaskMapper.selectByExample(example);

        // 过滤
        return Result.success(data);
    }

    /**
     * 批量插入,无事务
     * 
     * @param batch
     *            批量数据
     * 
     * @return result
     */
    public Result<List<ErrorWrapper<SysExportTask>>> insertBatch(List<SysExportTask> batch) {
        if (CollUtil.isEmpty(batch)) {
            return Result.buildError("数据不能为空");
        }
        ArrayList<ErrorWrapper<SysExportTask>> errorList = new ArrayList<>();

        // 批量插入
        for (SysExportTask task : batch) {
            if (sysExportTaskMapper.insertSelective(task) < 1) {
                ErrorWrapper<SysExportTask> error = new ErrorWrapper<>("插入失败", task);
                errorList.add(error);
            }
        }

        return errorList.size() > 1 ? Result.build(ResultCode.have_some_error, errorList) : Result.success();
    }

    /**
     * 批量插入,有事务
     * 
     * @param batch
     *            批量数据
     * 
     * @return result
     */
    @Transactional(rollbackFor = Exception.class)
    public Result<List<SysExportTask>> insertBatchTransactional(List<SysExportTask> batch) {
        if (CollUtil.isEmpty(batch)) {
            return Result.buildError("数据不能为空");
        }
        // 限制记录数
        if (batch.size() >= 10000) {
            return Result.buildError("事务接口记录不能大于10000");
        }
        // 批量插入
        for (SysExportTask task : batch) {
            if (sysExportTaskMapper.insertSelective(task) < 1) {
                throw new RuntimeException("插入失败, 记录: " + Jackson.toJsonString(task));
            }
        }

        return Result.success();
    }

    /**
     * 批量更新
     * 
     * @param batch
     *            批量数据
     * 
     * @return result
     */
    public Result<List<ErrorWrapper<SysExportTask>>> updateBatch(List<SysExportTask> batch)
            throws IllegalAccessException {
        if (CollUtil.isEmpty(batch)) {
            return Result.buildError("数据不能为空");
        }
        ArrayList<ErrorWrapper<SysExportTask>> errorList = new ArrayList<>();

        for (SysExportTask task : batch) {
            // 根据id 更新
            Long exportTaskId = task.getExportTaskId();
            if (ObjectUtil.isEmpty(exportTaskId)) {
                ErrorWrapper<SysExportTask> error = new ErrorWrapper<>("id不能为空", task);
                errorList.add(error);
                continue;
            }

            SysExportTask old = sysExportTaskMapper.selectByPrimaryKey(task.getExportTaskId());
            if (ObjectUtil.isEmpty(old)) {
                errorList.add(new ErrorWrapper<>("数据库没有此记录", task));
                continue;
            }

            // 替换更新属性值
            Field[] declaredFields = task.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                Object updateValue = field.get(task);
                if (ObjectUtil.isNotEmpty(updateValue)) {
                    field.set(old, updateValue);
                }
            }

            if (sysExportTaskMapper.updateByPrimaryKey(old) < 1) {
                errorList.add(new ErrorWrapper<>("入库失败", old));
            }

        }

        return errorList.size() > 1 ? Result.build(ResultCode.have_some_error, errorList) : Result.success();
    }

    /**
     * 批量更新, 事务
     * 
     * @param batch
     *            批量数据
     * 
     * @return result
     * 
     * @throws IllegalAccessException
     *             反射
     */
    public Result<List<ErrorWrapper<SysExportTask>>> updateBatchTransactional(List<SysExportTask> batch)
            throws IllegalAccessException {

        if (CollUtil.isEmpty(batch)) {
            return Result.buildError("数据不能为空");
        }
        // 限制记录数
        if (batch.size() >= 10000) {
            return Result.buildError("事务接口记录不能大于10000");
        }
        for (SysExportTask task : batch) {
            // 根据id 更新
            Long exportTaskId = task.getExportTaskId();
            if (ObjectUtil.isEmpty(exportTaskId)) {
                throw new RuntimeException("id不能为空, 记录: " + Jackson.toJsonString(task));
            }

            SysExportTask old = sysExportTaskMapper.selectByPrimaryKey(task.getExportTaskId());
            if (ObjectUtil.isEmpty(old)) {
                throw new RuntimeException("数据库没有此记录, 记录: " + task);
            }

            // 替换更新属性值
            Field[] declaredFields = task.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                Object updateValue = field.get(task);
                if (ObjectUtil.isNotEmpty(updateValue)) {
                    field.set(old, updateValue);
                }
            }

            if (sysExportTaskMapper.updateByPrimaryKey(old) < 1) {
                throw new RuntimeException("入库失败, 记录: " + Jackson.toJsonString(old));
            }

        }

        return Result.success();
    }

    /**
     * 批量删除
     * 
     * @param batch
     *            批量数据
     * 
     * @return result
     */
    public Result<List<ErrorWrapper<SysExportTask>>> deleteBatch(List<SysExportTask> batch) {

        if (CollUtil.isEmpty(batch)) {
            return Result.buildError("参数不能为空");
        }
        ArrayList<ErrorWrapper<SysExportTask>> errorList = new ArrayList<>();
        // 筛选id出来进行删除
        List<Long> ids = batch.parallelStream().filter(sysExportTask -> {
            if (ObjectUtil.isEmpty(sysExportTask.getExportTaskId())) {
                errorList.add(new ErrorWrapper<>("id不能为空", sysExportTask));
                return false;
            }
            return true;
        }).map(SysExportTask::getExportTaskId).collect(Collectors.toList());

        SysExportTaskExample example = new SysExportTaskExample();
        example.createCriteria().andExportTaskIdIn(ids);
        sysExportTaskMapper.deleteByExample(example);
        return errorList.size() > 1 ? Result.build(ResultCode.have_some_error, errorList) : Result.success();
    }

}
